/*
    This file is part of Posixcpp library.

    Posixcpp library is free software: you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public License
    as published by the Free Software Foundation, either version 3 of
    the License, or (at your option) any later version.

    Posixcpp library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU LesserGeneral Public
    License along with Posixcpp library. If not, see
    <http://www.gnu.org/licenses/>.
 */

/**
 * @file posix_spinlock.cpp
 * @brief Spinlock class implementation
 */

#include "posix_threads_spinlock.hpp"
#include "posixcpp.hpp"

using posix::threads::SpinLock;

using namespace posix::threads;

SpinLock::SpinLock( )
{
    POSIX_CALL_ASSERT((errno = pthread_spin_init(&m_handle,
                                                 PTHREAD_PROCESS_PRIVATE)) == 0);
}

SpinLock::~SpinLock( )
{
    POSIX_CALL_ASSERT((errno = pthread_spin_destroy(&m_handle)) == 0);
}

void SpinLock::lock( )
{
    POSIX_CALL_ASSERT((errno = pthread_spin_lock(&m_handle)) == 0);
}

void SpinLock::unlock( )
{
    POSIX_CALL_ASSERT((errno = pthread_spin_unlock(&m_handle)) == 0);
}

bool SpinLock::tryLock( )
{
    int res = pthread_spin_trylock(&m_handle);
    switch (res)
    {
    case 0:
        return true;
    case EBUSY:
        return false;
    default:
        throw std::system_error(res, std::system_category());
        return false;
    }
}
